﻿#pragma once
/**
@author 何炜
@date 2011/5/20
@brief .
@details
*/
#include "GLLObjMgr.h"
#include "GLLSystem.h"
#include "GLLLevelThread.h"
#include "GLLCamera.h"

namespace GLL
{
	class LevelManager;

	class LevelEvent
	{
	public:
		virtual void OnObjectLoaded(LvlObj*) = 0;
		virtual void OnObjectDeleted(LvlObj*) = 0;
	};

	/**Level，场景管理类
	多线程加载
	维护场景内各种物体
	维护场景的各种属性
	一个Level只负责管理当前Level中的所有物体*/
	class Level : public ObjectManager
	{
	public:
		//-----------------------------------------------------------------------------
		//property
		typedef General_ID ID;
		const ID _id;///<不可改变.
		const String _strID;///<不可改变.
		LevelManager* const _Mgr;///<不可改变.
		LevelEvent* _event;

		Level(LevelManager*, ID id);

		/**初始.
		产生物品创建线程*/
		void Init();

		/*清理.
		等所有线程结束后，才会继续*/
		void Final();

		void Update(TimeMS ms);

		void SetEventCallback(LevelEvent* e);
		Index AddLoadingThread();
		uint GetLoadingThreadNum();
		void RemoveFirstLoadingThread();
		String GetName(){return _name;}
		LevelThreadLoad* GetLoadingThread();

		//-----------------------------------------------------------------------------
		//object:
		LvlObjSrdPtr CreateObject(LvlObj::ID oid);
		bool HasObject(LvlObj::ID oid){return _HasObject(oid);}
		ObjSrdPtr FindObject(LvlObj::ID oid){	return _FindObject(oid);}

		void AddCamera(CamSrdPtr);
		void RemoveCamera(CamSrdPtr);

		/**.*/
		void PutToLoadQueue(ObjSrdPtr);

		/**.*/
		void PutToUnloadQueue(LvlObj::ID);

		/**.*/
		void PushAllOjbectsToUnloadQueue();

		//-----------------------------------------------------------------------------
		//render:
		void SetShadowTech_spec();

	protected:
		//-----------------------------------------------------------------------------
		//property
		String _name;
		bool _lifeIsOver;

		void OnInit_spec();
		void OnFinal_spec();

		//-----------------------------------------------------------------------------
		//object:
		friend class LvlObj;

		//多条读取线程
		typedef std::vector<LevelThreadLoad*> LoadingThreadVec;
		LoadingThreadVec _loadingThreads;

		void DeleteLoadingThread(LevelThreadLoad* p);
		LevelThreadLoad* GetLoadingThread(Index idx);

		///一条删除线程.
		LevelThreadUnload _unloadingThread;
		///预加载线程
		LevelThreadPreLoad _preThread;
		///读取后续
		LevelThreadPostLoad _ploadThread;
		///后期卸载线程
		LevelThreadPost _postThread;

		/**在主线程中调用.
		*/
		void _OnLoadingBegin_spec(LevelThreadType);

		/**在主线程中调用.
		*/
		void _OnLoadingEnd_spec(LevelThreadType);

		/**在读取线程中调用.
		*/
		void _OnLoadingThreadBegin_spec(LevelThreadType);

		/**在读取线程中调用.
		*/
		void _OnLoadingThreadEnd_spec(LevelThreadType);

	protected:
		friend class LevelManager;
		friend class LevelThread;
		friend class LevelThreadLoad;
		friend class LevelThreadUnload;
		void operator = (Level& l){}

#ifdef GLL_OGRE
	public:
		Ogre::SceneManager* _smOgre;
		Ogre::SceneNode* _node;
#endif GLL_OGRE

	};

	typedef boost::shared_ptr<Level> LvlSrdPtr;
	typedef boost::weak_ptr<Level> LvlRefPtr;

};//GLL
